let c = document.getElementById('c'),
    ctx = c.getContext('2d');
    mx = 0, my = 0;
const handleWindowResize = () => {
  c.width = window.innerWidth * window.devicePixelRatio;
  c.height = window.innerHeight * window.devicePixelRatio;
  mx = c.width / 2;
  my = c.height / 2;
}
window.addEventListener('resize', handleWindowResize, false);
handleWindowResize();

/**
 * 平面3D的本质，是将视角固定在z轴方向上的某个点，观察空间内的另一个点，通过相似直角三角形将被观察点向 xy 平面进行投影。
 * 详细的推导过程可以参考 https://www.jianshu.com/p/e3ebe08dddad 这篇文章
 */

ctx.translate(mx, my);
const observer = { x: 0, y: 0, z: 300 }; // 观察点

// 绘制立方体
const drawCube = (ctx, cubeMap) => {
  let drawCubeMap = cubeMap.map(v => transformPointToXY(observer, v, 0, 0));

  ctx.save();
  ctx.lineWidth = 1;
  ctx.strokeStyle = 'red';
  ctx.beginPath();

  ctx.moveTo(drawCubeMap[0].x, drawCubeMap[0].y);
  ctx.lineTo(drawCubeMap[1].x, drawCubeMap[1].y);
  ctx.lineTo(drawCubeMap[2].x, drawCubeMap[2].y);
  ctx.lineTo(drawCubeMap[3].x, drawCubeMap[3].y);
  ctx.lineTo(drawCubeMap[0].x, drawCubeMap[0].y);

  ctx.moveTo(drawCubeMap[4].x, drawCubeMap[4].y);
  ctx.lineTo(drawCubeMap[5].x, drawCubeMap[5].y);
  ctx.lineTo(drawCubeMap[6].x, drawCubeMap[6].y);
  ctx.lineTo(drawCubeMap[7].x, drawCubeMap[7].y);
  ctx.lineTo(drawCubeMap[4].x, drawCubeMap[4].y);

  ctx.moveTo(drawCubeMap[0].x, drawCubeMap[0].y);
  ctx.lineTo(drawCubeMap[4].x, drawCubeMap[4].y);

  ctx.moveTo(drawCubeMap[1].x, drawCubeMap[1].y);
  ctx.lineTo(drawCubeMap[5].x, drawCubeMap[5].y);

  ctx.moveTo(drawCubeMap[2].x, drawCubeMap[2].y);
  ctx.lineTo(drawCubeMap[6].x, drawCubeMap[6].y);

  ctx.moveTo(drawCubeMap[3].x, drawCubeMap[3].y);
  ctx.lineTo(drawCubeMap[7].x, drawCubeMap[7].y);

  ctx.closePath();
  ctx.stroke();
  ctx.restore();
}

let cubeMap = getCube(observer, {x: 0, y: 0, z: 0}, 100);

new TWEEN.Tween({ rotate: 0 }).to({
  rotate: 360
}, 5000)
  .repeat(Infinity)
  .easing(TWEEN.Easing.Linear.None)
  .onUpdate((obj) => {
    ctx.clearRect(-mx, -my, c.width, c.height);
    drawCube(ctx, cubeMap.map(v => transformPointRotateByY(v, obj.rotate)));
  })
  .start();

(function animate () {
  let id = requestAnimationFrame(animate);
  let ret = TWEEN.update();
  if(!ret) cancelAnimationFrame(id);
})();